package cn.iocoder.yudao.module.wecom.controller.admin.user;

import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.wecom.convert.user.WeUserConverter;
import cn.iocoder.yudao.module.wecom.service.acqlinkrange.AcqLinkRangeService;
import cn.iocoder.yudao.module.wecom.service.chatgroup.WeChatGroupService;
import cn.iocoder.yudao.module.wecom.service.customer.WeCustomerService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.annotation.security.PermitAll;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;

import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

import cn.iocoder.yudao.module.wecom.controller.admin.user.vo.*;
import cn.iocoder.yudao.module.wecom.dal.dataobject.user.WeUserDO;
import cn.iocoder.yudao.module.wecom.service.user.WeUserService;

@Tag(name = "管理后台 - 企微员工")
@RestController
@RequestMapping("/wecom/we-user")
@Validated
public class WeUserController {

    @Resource
    private WeUserService weUserService;

    @Resource
    private WeCustomerService weCustomerService;

    @Resource
    private WeChatGroupService weChatGroupService;

    @Resource
    private AcqLinkRangeService acqLinkRangeService;

    @Resource
    private AdminUserApi adminUserApi;

    @PostMapping("/sync-user")
    @Operation(summary = "同步通讯录")
    @PreAuthorize("@ss.hasPermission('wecom:we-user:create')")
    public CommonResult<Boolean> syncWeUser() {
        return success(weUserService.syncWeUser());
    }

    @GetMapping("/get-auth-url")
    @Operation(summary = "构建授权链接")
    public CommonResult<String> getAuthUrl() {
        return success(weUserService.getAuthUrl(TenantContextHolder.getTenantId(), getLoginUserId()));
    }

    @GetMapping("/get-auth-url-by-user")
    @Operation(summary = "构建授权链接")
    @Parameter(name = "id", description = "用户ID")
    public CommonResult<String> getAuthUrl(@RequestParam("id") Long userId) {
        return success(weUserService.getAuthUrl(userId, TenantContextHolder.getTenantId()));
    }

    @GetMapping("/get-bind-user")
    @Operation(summary = "获取绑定的企业微信用户")
    public CommonResult<WeUserRespVO> getBindUser() {
        return success(weUserService.getBindUser());
    }

    @PostMapping("/unbind-user")
    @Operation(summary = "解绑用户")
    public CommonResult<Boolean> unBindUser() {
        weUserService.unBindUser();
        return success(true);
    }


    @PostMapping("/create")
    @Operation(summary = "创建企微员工")
    @PreAuthorize("@ss.hasPermission('wecom:we-user:create')")
    public CommonResult<Long> createWeUser(@Valid @RequestBody WeUserSaveReqVO createReqVO) {
        return success(weUserService.createWeUser(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新企微员工")
    @PreAuthorize("@ss.hasPermission('wecom:we-user:update')")
    public CommonResult<Boolean> updateWeUser(@Valid @RequestBody WeUserSaveReqVO updateReqVO) {
        weUserService.updateWeUser(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除企微员工")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('wecom:we-user:delete')")
    public CommonResult<Boolean> deleteWeUser(@RequestParam("id") Long id) {
        weUserService.deleteWeUser(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得企微员工")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('wecom:we-user:query')")
    public CommonResult<WeUserRespVO> getWeUser(@RequestParam("id") Long id) {
        WeUserDO weUser = weUserService.getWeUser(id);
        return success(BeanUtils.toBean(weUser, WeUserRespVO.class));
    }

    @GetMapping("/simple-list")
    @Operation(summary = "获得企微员工 - 简单查询接口")
    @PreAuthorize("@ss.hasPermission('wecom:we-user:query')")
    @Parameter(name = "name", description = "员工名称", required = false)
    public CommonResult<List<WeUserRespVO>> getWeUserSimpleList(
            @RequestParam(value = "name", required = false) String name
    ) {
        WeUserPageReqVO pageReqVO = new WeUserPageReqVO();
        pageReqVO.setBindStatus(1);
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        pageReqVO.setNickname(name);
        PageResult<WeUserDO> page = weUserService.getWeUserPage(pageReqVO);
        PageResult<WeUserRespVO> list = BeanUtils.toBean(page, WeUserRespVO.class);
        return success(list.getList());
    }


    @PostMapping("/get-bind-status")
    @Operation(summary = "获得企微员工账户绑定状态")
    public CommonResult<Map<Long, WeUserDO>> getWeUserBindStatus(@RequestBody List<Long> sysUserIdList) {
        Map<Long, WeUserDO> result = weUserService.getWeUserBindStatus(sysUserIdList);
        return success(result);
    }

    @GetMapping("/page")
    @Operation(summary = "获得企微员工分页")
    @PreAuthorize("@ss.hasPermission('wecom:we-user:query')")
    public CommonResult<PageResult<WeUserRespVO>> getWeUserPage(@Valid WeUserPageReqVO pageReqVO) {
        PageResult<WeUserDO> pageResult = weUserService.getWeUserPage(pageReqVO);

        List<Long> sysUserIdList = pageResult.getList().stream().map(WeUserDO::getSysUserId).collect(Collectors.toList());
        List<Long> idList = sysUserIdList.stream().filter(Objects::nonNull).collect(Collectors.toList());
        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(idList);
        PageResult<WeUserRespVO> convert = WeUserConverter.INSTANCE.convert(pageResult, userMap);
        convert.getList().forEach(weUserRespVO -> {
            // 获取跟进客户列表
//            weUserRespVO.setCustomerList(weCustomerService.getCustomerIdsByUserId(weUserRespVO.getSysUserId()));
            weUserRespVO.setCustomerCount(weCustomerService.getCustomerCountByUserId(weUserRespVO.getSysUserId()));
            weUserRespVO.setChatGroupCount(weChatGroupService.getChatGroupCountByWeUserId(weUserRespVO.getWeUserId()));

            if (Objects.equals(true, pageReqVO.getShowCount())) {
                // 获取群聊
//                weUserRespVO.setChatGroupList(weChatGroupService.getChatIdListByWeUserId(weUserRespVO.getWeUserId()));
                // 获取获客链接
                weUserRespVO.setAcqList(acqLinkRangeService.getLinkIdListByWeUserId(weUserRespVO.getWeUserId()));
            }
        });
        return success(convert);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出企微员工 Excel")
    @PreAuthorize("@ss.hasPermission('wecom:we-user:export')")
    @OperateLog(type = EXPORT)
    public void exportWeUserExcel(@Valid WeUserPageReqVO pageReqVO,
                                  HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<WeUserDO> list = weUserService.getWeUserPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "企微员工.xls", "数据", WeUserRespVO.class,
                BeanUtils.toBean(list, WeUserRespVO.class));
    }

    @OperateLog(enable = false)
    @Operation(description = "企微用户登录，扫码登录；")
    @GetMapping("/login")
    @PermitAll
    @TenantIgnore
    public CommonResult<OAuth2AccessTokenRespDTO> login(
            @RequestParam("code") String code) {
        return success(weUserService.weUserLogin(code));
    }

    @OperateLog(enable = false)
    @Operation(description = "企微内部浏览器静默登录；")
    @GetMapping("/login-inner")
    @PermitAll
    @TenantIgnore
    public CommonResult<OAuth2AccessTokenRespDTO> loginInner(
            @RequestParam("code") String code) {
        return success(weUserService.weUserLoginInner(code));
    }

    @OperateLog(enable = false)
    @Operation(description = "企微内部浏览器静默登录；")
    @GetMapping("/quick-login")
    @TenantIgnore
    @PermitAll
    public CommonResult<OAuth2AccessTokenRespDTO> quickLogin(@Valid WeComQuickLoginReqVo reqVo) {
        AtomicReference<OAuth2AccessTokenRespDTO> respVO = new AtomicReference<>();
        TenantUtils.executeIgnore(() -> {
            respVO.set(weUserService.weUserQuickLogin(reqVo));
        });

        return CommonResult.success(respVO.get());
    }

}